# -*- coding: UTF-8 -*-

import datetime
import time
import os
from common import printLog,TradeSide,getMinOrderQty,simpleTWAP
from DMAClass import PriceType,DMAOrder,OrderBook
from config import DMA_DIR
#from strategySignal import positionMoves4DMA,executeMins

'''
OneQuant DEMO: 

demo场景: 简单下单及撤单 

重要:在测试环境使用时,请修改 config.py  DMA_DIR 目录及 本程序中 my_orders 的账号信息。
     相关使用规范请查阅【DMA使用手册】

本示例完成
    1:本示例为简单展示如何使用DMA,将订单及撤单指令写入算法文件,完成指令.
    1:用户在写入DMA导入文件时，请确保传入的本地订单号custBatchNo 为32位无符号整型(uint32)且为当天唯一

'''

def order_dma(fd,dmaOrder:DMAOrder):

    dma_order_str=dmaOrder.toCSVFormat()
    fd.write(dma_order_str+"\n")   # 写入DMA文件 
    printLog("写入报单文件:[%-5s]:股票:%s,价格:%s,数量:%d,上浮ticks:%d" % ( TradeSide(dmaOrder.tradeSide).name,dmaOrder.symbol,PriceType(dmaOrder.priceType).name,dmaOrder.targetQty,dmaOrder.ticks),flush = True)

def cancel_dma(fd,order:DMAOrder):

    updTime=datetime.datetime.now().strftime("%Y-%m-%d %H%M%S.%f")[11:-3]   # hhmmss.sss
    cancel_dma_str="%s,%s" % (updTime,order.custBatchNo)
    fd.write(cancel_dma_str+"\n")      # 写入撤单文件
    printLog('写入撤单文件:' + cancel_dma_str,flush = True)

def init_order_cancel_files(order_file,cancel_file):
    if not os.path.exists(order_file):
        with open(order_file,'w') as f:
            f.write("updTime,custBatchNo,acctType,acct,symbol,tradeSide,targetQty,algoId,priceType,ticks,highLimitPrice,lowLimitPrice" + "\n")
        printLog('创建DMA下单文件:' + order_file)
    if not os.path.exists(cancel_file):
        with open(cancel_file,'w') as f:
            f.write("updTime,custBatchNo" + "\n")
        printLog('创建DMA撤单文件:' + cancel_file)


if __name__ == '__main__':

    # 我的订单 (账号、账号类型、股票代码、方向、数量)
    my_orders = [('880100001155','UF0','000001.SZ',TradeSide.BUY,500),('880100001155','UF0','000725.SZ',TradeSide.BUY,1000),('880100001155','UF0','601398.SH',TradeSide.BUY,1000)]

    order_params="""
    custBatchNo=1
    acct=S00000099
    acctType=S0
    algoId=DMA
    symbol=000000.SH
    priceType=P8
    targetQty=100
    tradeSide=1
    ticks=0
    lowLimitPrice=0
    highLimitPrice=0
    """
    
    order_params = {kv.split("=")[0]:kv.split("=")[1] for kv in order_params.replace(" ","").split()}

    # 初始化下单文件及撤单文件,订单簿orderbook,启动orderbook
    date= datetime.datetime.now().strftime("%Y%m%d")
    order_file =os.path.join(DMA_DIR,    'algoOrder_' + date + '.csv')
    cancel_file=os.path.join(DMA_DIR,'algoOrderStop_' + date + '.csv')

    init_order_cancel_files(order_file,cancel_file)
    
    orderbook=OrderBook(DMA_DIR,date)
    orderbook.init_history()
    orderbook.run()             # 后台运行 读取各个回写文件

    try:
        with open(order_file,'a',buffering=1) as order_f,open(cancel_file,'a',buffering=1) as cancel_f:         # 注意只能追加模式
                        
            updTime=datetime.datetime.now().strftime("%Y-%m-%d %H%M%S.%f")[11:-3]

            for order_element in my_orders:
                    (acct,acctType,stock,tradeSide,qty ) = order_element

                    # 下单要素的填充
                    updTime=datetime.datetime.now().strftime("%Y-%m-%d %H%M%S.%f")[11:-3]
                    custBatchNo=   int(float(updTime)*pow(10,3)) + int(stock[0:6])
                    order_params['acct'] = acct
                    order_params['acctType'] = acctType
                    order_params['symbol'] = stock
                    order_params['custBatchNo'] = custBatchNo
                    order_params['tradeSide'] = tradeSide.value
                    order_params['updTime']   = updTime
                    # 下单价格: 买:买1价  或 卖: 卖1价
                    order_params['priceType'] = PriceType.BID_1.value  if TradeSide.isBuy(tradeSide) else PriceType.ASK_1.value
                    order_params['ticks']=0  if TradeSide.isBuy(tradeSide) else 0                          
                    # 下单数量
                    order_params['targetQty']= qty
                    # 下单
                    dma_order = DMAOrder()
                    dma_order.parseDMAOrder(order_params)
                    order_dma(order_f,dma_order)

            # 撤单控制
            time.sleep(10) #  等待10秒，不成交，则 进行撤单
            for order_element in my_orders:
                (acct,acctType,stock,tradeSide,qty ) = order_element
                unfinished_orders = orderbook.getUnfinishOrders(stock,tradeSide,acct)
                # 进行撤单
                for order in unfinished_orders:
                    cancel_dma(cancel_f,order)

    except Exception as e:
        printLog(str(e))
        raise(e)
    
    finally:
        orderbook.stop()
